package com.zb.order.controller;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zb.annotation.SystemLog;
import com.zb.constant.OperationLogModuleType;
import com.zb.constant.OperationLogType;
import com.zb.entity.AccounLoginInfo;
import com.zb.entity.ZjWorkOrder;
import com.zb.exception.SMSException;
import com.zb.exception.ZbException;
import com.zb.order.service.ConWorkOrderService;
import com.zb.result.PageUtil;
import com.zb.result.Result;
import com.zb.service.*;
import com.zb.service.impl.WorkServiceLog;
import com.zb.utils.TokenUtil;
import com.zb.vo.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.ibatis.annotations.Param;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * <p>
 * 工单表 前端控制器
 * </p>
 *
 * @author WEN
 * @since 2023-09-20
 */
@Api(tags = "工单类接口")
@RestController
@RequestMapping("/work/order")
public class ZjWorkOrderController {
    @Resource
    private ConWorkOrderService conWorkOrderService;
    @Resource
    private ZjWorkOrderService workOrderService;
    @Resource
    private ZjWorkModuleFieldService workModuleFieldService;
    @Resource
    private ZjWorkLogService workLogService;
    @Resource
    private ZjWorkReminderService workReminderService;
    @Resource
    private ZjWorkLeaveMessageService workLeaveMessageService;
    @Resource
    private WorkRepeatService workRepeatService;

    @ApiOperation("获取重复工单配置")
    @PostMapping("/getWorkRepeatConfig")
    public Result getWorkRepeatConfig(HttpServletRequest request, @RequestBody WorkRepeatSearchVo search) {
        Long custAccId = TokenUtil.getcustAccIdByToken(request);
        return Result.success("获取重复工单配置成功").data(PageUtil.row(workRepeatService.getWorkRepeatConfig(custAccId, search)));
    }

    @SystemLog(moduleType = OperationLogModuleType.WORK_ORDER_TYPE, type = OperationLogType.INSERT_UPDATE, remark = "工单管理-工单列表 - 创建或修改工单")
    @ApiOperation("创建工单")
    @PostMapping("/save")
    public Result save(HttpServletRequest request, @RequestBody @Valid OrderVo orderVo) {
        AccounLoginInfo loginInfo = TokenUtil.getAccountLoginInfo(request);
        Map<String, Object> save = conWorkOrderService.save(loginInfo, false, orderVo);
        if (save == null) {
            return Result.error(400, "两秒内只能创建一个工单！");
        }
        return Result.success(null == orderVo.getId()? "创建工单成功" : "修改工单成功");
    }

    @SystemLog(moduleType = OperationLogModuleType.WORK_ORDER_TYPE, type = OperationLogType.UPDATE, remark = "工单管理-工单列表 - 更新工单信息")
    @ApiOperation("更新工单信息")
    @PostMapping("/updateInfo")
    public Result updateInfo(HttpServletRequest request, @RequestBody OrderVo orderVo) {
        AccounLoginInfo loginInfo = TokenUtil.getAccountLoginInfo(request);
        workOrderService.updateInfo(orderVo, loginInfo);
        return Result.success("工单信息更新成功");
    }

    @ApiOperation("工单原始参数获取")
    @PostMapping("/copySave")
    public Result copySave(HttpServletRequest request, @RequestBody OrderVo orderVo) {
        AccounLoginInfo loginInfo = TokenUtil.getAccountLoginInfo(request);
        OrderVo res = conWorkOrderService.copySave(loginInfo, false, orderVo.getId());
        if (res != null){
            return Result.success("工单原始参数获取成功").data("row", res);
        }else {
            return Result.error(10001,"来自旧版本的工单无法获取原始参数");
        }
    }

    @ApiOperation("获取工单列表状态数量")
    @GetMapping("/getOrderStatusQty")
    public Result getOrderStatusQty(HttpServletRequest request) {
        Long custAccId = TokenUtil.getcustAccIdByToken(request);
        return Result.success("获取工单列表状态数量成功").data(PageUtil.row(workOrderService.getOrderListStatusQty(custAccId)));
    }

    @ApiOperation("获取工单列表搜索条件的工单自定义搜索字段")
    @GetMapping("/getOrderListSelectField")
    public Result getOrderListSelectField(HttpServletRequest request) {
        Long custAccId = TokenUtil.getcustAccIdByToken(request);
        return Result.success().data("rows", workModuleFieldService.getOrderListSelectField(custAccId));
    }

    @ApiOperation("获取工单列表表头的工单自定义字段")
    @GetMapping("/getOrderListTableTitleField")
    public Result getOrderListTableTitleField(HttpServletRequest request) {
        Long custAccId = TokenUtil.getcustAccIdByToken(request);
        return Result.success().data("rows", workModuleFieldService.getOrderListTableTitleField(custAccId));
    }

    @ApiOperation("获取工单列表")
    @PostMapping("/getList")
    public Result getList(HttpServletRequest request, @RequestBody OrderListSelectVo selectVo) {
        AccounLoginInfo loginInfo = TokenUtil.getAccountLoginInfo(request);
        return Result.success("获取工单列表成功").data(conWorkOrderService.getList(loginInfo, selectVo));
    }

    @ApiOperation("获取归档列表状态数量")
    @GetMapping("/getOrderArchivedStatusQty")
    public Result getOrderArchivedStatusQty(HttpServletRequest request) {
        Long custAccId = TokenUtil.getcustAccIdByToken(request);
        return Result.success("获取归档列表状态数量成功").data(PageUtil.row(conWorkOrderService.getOrderArchivedStatusQty(custAccId)));
    }

    @ApiOperation("获取工单归档列表")
    @PostMapping("/getOrderArchivedList")
    public Result getOrderArchivedList(HttpServletRequest request, @RequestBody OrderArchivedListSearchVo archivedListSearchVo) {
        AccounLoginInfo loginInfo = TokenUtil.getAccountLoginInfo(request);
        return Result.success("获取工单归档列表成功").data(conWorkOrderService.getOrderArchivedList(loginInfo, archivedListSearchVo));
    }

    @ApiOperation("获取结算列表状态数量")
    @GetMapping("/getOrderSettlementStatusQty")
    public Result getOrderSettlementStatusQty(HttpServletRequest request) {
        Long custAccId = TokenUtil.getcustAccIdByToken(request);
        return Result.success("获取结算列表状态数量成功").data(PageUtil.row(conWorkOrderService.getOrderSettlementStatusQty(custAccId)));
    }

    @ApiOperation("获取工单结算列表")
    @PostMapping("/getOrderSettlementList")
    public Result getOrderSettlementList(HttpServletRequest request, @RequestBody OrderSettlementListSearchVo searchVo) {
        AccounLoginInfo loginInfo = TokenUtil.getAccountLoginInfo(request);
        return Result.success("获取工单结算列表成功").data(conWorkOrderService.getOrderSettlementList(loginInfo, searchVo));
    }

    @ApiOperation("根据工单ID获取工单详情")
    @GetMapping("/getOrderDetail/{id}")
    public Result getOrderDetail(@PathVariable @ApiParam(value = "工单ID", required = true) Long id) {
        return Result.success("获取工单详情成功").data("row", conWorkOrderService.getOrderDetail(id));
    }

    @ApiOperation("根据工单ID获取工单商品")
    @PostMapping("/getOrderGoodsDetail/{workId}")
    public Result getOrderGoodsDetail(@PathVariable @ApiParam(value = "工单ID", required = true) Long workId, @RequestBody PageUtil pageUtil) {
        return Result.success("获取工单商品信息成功").data(conWorkOrderService.getOrderGoodsDetail(workId, pageUtil));
    }

    @ApiOperation("根据工单ID获取工单操作记录列表")
    @PostMapping("/getOrderLog/{workId}")
    public Result getOrderLogList(@PathVariable @ApiParam(value = "工单ID", required = true) Long workId, @RequestBody PageUtil pageUtil) {
        return Result.success("获取工单操作记录列表成功").data(workLogService.getOrderLogList(workId, pageUtil));
    }

    @SystemLog(moduleType = OperationLogModuleType.WORK_ORDER_TYPE, type = OperationLogType.UPDATE, remark = "工单管理-工单列表 - 工单催单")
    @ApiOperation("工单催单")
    @PostMapping("/saveReminder")
    public Result saveReminder(HttpServletRequest request, @RequestBody @Valid OrderReminderVo reminderVo) throws ZbException {
        AccounLoginInfo loginInfo = TokenUtil.getAccountLoginInfo(request);
        conWorkOrderService.saveReminder(loginInfo, reminderVo);
        return Result.success("催单成功");
    }

    @ApiOperation("根据工单ID获取工单催单列表")
    @PostMapping("/getReminderList/{workId}")
    public Result getReminderList(@PathVariable @ApiParam(value = "工单ID", required = true) Long workId, @RequestBody PageUtil pageUtil) {
        return Result.success("获取工单催单列表成功").data(workReminderService.getReminderList(workId, pageUtil));
    }

    @SystemLog(moduleType = OperationLogModuleType.WORK_ORDER_TYPE, type = OperationLogType.UPDATE, remark = "工单管理-工单列表 - 批量分配客服")
    @ApiOperation("批量分配客服")
    @PutMapping("/dispatchOrderEmp/{empId}")
    public Result dispatchOrderEmp(HttpServletRequest request, @PathVariable @ApiParam(value = "客服人员ID", required = true) Long empId,
                                   @RequestBody @ApiParam(value = "工单ID", required = true) List<Long> workIds) {
        AccounLoginInfo loginInfo = TokenUtil.getAccountLoginInfo(request);
        workOrderService.dispatchOrderEmp(loginInfo, workIds, empId);
        return Result.success("分配客服成功");
    }

    @SystemLog(moduleType = OperationLogModuleType.WORK_ORDER_TYPE, type = OperationLogType.UPDATE, remark = "工单管理-工单列表 - 批量更新工单流程为完成")
    @ApiOperation("批量更新工单流程为完成")
    @PutMapping("/finishOrder")
    public Result finishOrder(HttpServletRequest request, @RequestBody @Valid OrderEventVo orderEventVo) {
        AccounLoginInfo loginInfo = TokenUtil.getAccountLoginInfo(request);
        conWorkOrderService.finishOrder(loginInfo, orderEventVo);
        return Result.success("更改工单流程为完成状态成功");
    }

    @SystemLog(moduleType = OperationLogModuleType.WORK_ORDER_TYPE, type = OperationLogType.UPDATE, remark = "工单管理-工单列表 - 批量更新工单流程为取消")
    @ApiOperation("批量更新工单流程为取消")
    @PutMapping("/cancelOrder")
    public Result cancelOrder(HttpServletRequest request, @RequestBody @Valid OrderEventVo orderEventVo) {
        AccounLoginInfo loginInfo = TokenUtil.getAccountLoginInfo(request);
        conWorkOrderService.cancelOrder(loginInfo, orderEventVo);
        return Result.success("更改工单流程为取消状态成功");
    }

    @SystemLog(moduleType = OperationLogModuleType.WORK_ORDER_TYPE, type = OperationLogType.UPDATE, remark = "工单管理-工单列表 - 工单预约时间")
    @ApiOperation("工单预约时间")
    @PutMapping("/reservationTime")
    public Result reservationTime(HttpServletRequest request, @RequestBody @Valid OrderReservationTimeVo orderReservationTimeVo) {
        AccounLoginInfo loginInfo = TokenUtil.getAccountLoginInfo(request);
        conWorkOrderService.reservationTime(loginInfo, orderReservationTimeVo);
        return Result.success("预约时间成功");
    }

    @SystemLog(moduleType = OperationLogModuleType.WORK_ORDER_TYPE, type = OperationLogType.UPDATE, remark = "工单管理-工单列表 - 派单给务商")
    @ApiOperation("派单给务商")
    @PutMapping("/orderDispatchNetwork")
    public Result orderDispatchNetwork(HttpServletRequest request, @RequestBody @Valid OrderDispatchNetworkVo orderDispatchNetworkVo) {
        AccounLoginInfo loginInfo = TokenUtil.getAccountLoginInfo(request);
        conWorkOrderService.orderDispatchNetwork(loginInfo, orderDispatchNetworkVo);
        return Result.success("派单成功");
    }

    @SystemLog(moduleType = OperationLogModuleType.WORK_ORDER_TYPE, type = OperationLogType.UPDATE, remark = "工单管理-工单列表 - 改派服务商")
    @ApiOperation("改派服务商")
    @PutMapping("/changeNetwork")
    public Result changeNetwork(HttpServletRequest request, @RequestBody @Valid OrderChangeNetworkVo changeNetworkVo) {
        AccounLoginInfo loginInfo = TokenUtil.getAccountLoginInfo(request);
        conWorkOrderService.changeNetwork(loginInfo, changeNetworkVo);
        return Result.success("申请改派服务成功");
    }

    @SystemLog(moduleType = OperationLogModuleType.WORK_ORDER_TYPE, type = OperationLogType.UPDATE, remark = "工单管理-工单列表 - 改派工单客服")
    @ApiOperation("改派工单客服")
    @PutMapping("/changeServiceEmp")
    public Result changeServiceEmp(HttpServletRequest request, @RequestBody @Valid OrderChangeServiceEmpVo changeServiceEmpVo) {
        AccounLoginInfo loginInfo = TokenUtil.getAccountLoginInfo(request);
        conWorkOrderService.changeServiceEmp(loginInfo, changeServiceEmpVo);
        return Result.success("客服改派成功");
    }

    @SystemLog(moduleType = OperationLogModuleType.WORK_ORDER_TYPE, type = OperationLogType.UPDATE, remark = "工单管理-工单列表详情 - 工单留言")
    @ApiOperation("保存工单留言")
    @PostMapping("/saveWorkLeaveMessage")
    public Result saveWorkLeaveMessage(HttpServletRequest request, @RequestBody @Valid OrderLeaveMessageVo orderLeaveMessageVo) {
        AccounLoginInfo loginInfo = TokenUtil.getAccountLoginInfo(request);
        conWorkOrderService.saveWorkLeaveMessage(loginInfo, orderLeaveMessageVo);
        return Result.success("留言成功");
    }

    @ApiOperation("根据工单ID获取客服未读的工单留言")
    @PostMapping("/getWorkNotReadLeaveMessageCount/{workId}")
    public Result getWorkNotReadLeaveMessageCount(@PathVariable @ApiParam(value = "工单ID", required = true) Long workId) {
        return Result.success("获取客服未读的工单留言成功").data("row", workLeaveMessageService.getWorkNotReadLeaveMessageCount(workId));
    }

    @ApiOperation("根据工单ID获取工单留言")
    @PostMapping("/getWorkLeaveMessageList/{workId}")
    public Result getWorkLeaveMessageList(@PathVariable @ApiParam(value = "工单ID", required = true) Long workId,
                                          @RequestBody PageUtil pageUtil) {
        return Result.success("获取工单留言成功").data(conWorkOrderService.getWorkLeaveMessageList(workId, pageUtil));
    }

    @SystemLog(moduleType = OperationLogModuleType.WORK_ORDER_TYPE, type = OperationLogType.UPDATE, remark = "工单管理-工单列表详情 - 根据工单ID更新工单未读留言")
    @ApiOperation("根据工单ID更新工单未读留言")
    @PutMapping("/updateWorkNotReadLeaveMessage/{workId}")
    public Result updateWorkNotReadLeaveMessage(@PathVariable @ApiParam(value = "工单ID", required = true) Long workId) {
        workLeaveMessageService.updateWorkEmpNotReadLeaveMessageByWorkId(workId);
        return Result.success("更新工单未读留言成功");
    }

    @ApiOperation("根据工单ID获取服务商地址")
    @GetMapping("/getOrderNetworkAddress")
    public Result getOrderNetworkAddress(Long workId) {
        return Result.success("获取服务商地址成功").data("row", conWorkOrderService.getOrderNetworkAddress(workId));
    }

    @ApiOperation("工单归档")
    @PostMapping("/orderArchived")
    public Result orderArchived(HttpServletRequest request, @RequestBody @Valid OrderArchivedVo archivedVo) {
        AccounLoginInfo loginInfo = TokenUtil.getAccountLoginInfo(request);
        conWorkOrderService.orderArchived(loginInfo, archivedVo);
        return Result.success("工单归档成功");
    }

    @ApiOperation("获取工单详情的工单总费用")
    @GetMapping("/getOrderTotalFee/{workId}")
    public Result getOrderTotalFee(@PathVariable @ApiParam(value = "工单ID", required = true) Long workId) {
        return Result.success("获取工单总费用成功").data(PageUtil.row(conWorkOrderService.getOrderTotalFee(workId)));
    }

    @ApiOperation("根据工单ID获取待审核改派服务商的工单")
    @GetMapping("/getWaitCheckWorkReassign/{workId}")
    public Result getWaitCheckWorkReassign(@PathVariable @ApiParam(value = "工单ID", required = true) Long workId) {
        return Result.success("获取待审核改派服务商的工单成功").data(PageUtil.row(conWorkOrderService.getWaitCheckWorkReassign(workId)));
    }

    @ApiOperation("审核改派服务商的工单")
    @PostMapping("/checkWorkReassign/{workId}")
    public Result checkWorkReassign(HttpServletRequest request, @PathVariable @ApiParam(value = "工单ID", required = true) Long workId,
                                    @RequestBody @Valid WorkCheckReassignVo reassignVo) {
        AccounLoginInfo loginInfo = TokenUtil.getAccountLoginInfo(request);
        conWorkOrderService.checkWorkReassign(loginInfo, workId, reassignVo);
        return Result.success("审核改派服务商的工单成功");
    }

    @ApiOperation("根据工单ID获取工单待结单审核")
    @GetMapping("/getWaitCheckStatementOrder/{workId}")
    public Result getWaitCheckStatementOrder(@PathVariable @ApiParam(value = "工单ID", required = true) Long workId) {
        return Result.success("获取工单待结单审核成功").data(PageUtil.row(conWorkOrderService.getWaitCheckStatementOrder(workId)));
    }

    @ApiOperation("审核结单")
    @PostMapping("/checkStatementOrder/{workId}")
    public Result checkStatementOrder(HttpServletRequest request, @PathVariable @ApiParam(value = "工单ID", required = true) Long workId,
                                      @RequestBody @Valid WorkCheckStatementVo checkStatementVo) {
        AccounLoginInfo loginInfo = TokenUtil.getAccountLoginInfo(request);
        conWorkOrderService.checkStatementOrder(loginInfo, workId, checkStatementVo);
        return Result.success("审核结单成功");
    }
    @ApiOperation("驳回结单")
    @PostMapping("/backStatementOrder/{workId}")
    public Result backStatementOrder(HttpServletRequest request, @PathVariable @ApiParam(value = "工单ID", required = true) Long workId) {
        AccounLoginInfo loginInfo = TokenUtil.getAccountLoginInfo(request);
        conWorkOrderService.backStatementOrder(loginInfo, workId);
        return Result.success("驳回结单成功");
    }
    @ApiOperation("根据工单ID获取待审核取消工单")
    @GetMapping("/getWaitCheckCancelOrder/{workId}")
    public Result getWaitCheckCancelOrder(@PathVariable @ApiParam(value = "工单ID", required = true) Long workId) {
        return Result.success("获取待审核取消工单成功").data(PageUtil.row(conWorkOrderService.getWaitCheckCancelOrder(workId)));
    }

    @ApiOperation("审核取消工单")
    @PostMapping("/checkCancelOrder/{workId}")
    public Result checkCancelOrder(HttpServletRequest request, @PathVariable @ApiParam(value = "工单ID", required = true) Long workId, @RequestBody @Valid WorkCheckCancelVo checkCancelVo) {
        AccounLoginInfo loginInfo = TokenUtil.getAccountLoginInfo(request);
        conWorkOrderService.checkCancelOrder(loginInfo, workId, checkCancelVo);
        return Result.success("审核取消工单成功");
    }

    @ApiOperation("获取待审核的工单事件")
    @GetMapping("/getWaitCheckOrderEvent/{workId}")
    public Result getWaitCheckOrderEvent(@PathVariable @ApiParam(value = "工单ID", required = true) Long workId) {
        return Result.success("获取待审核的工单事件成功").data(PageUtil.rows(conWorkOrderService.getWaitCheckOrderEvent(workId)));
    }

    @ApiOperation("发送结单核销码")
    @GetMapping("/sendOrderStatementWriteOffCode/{workId}")
    public Result sendOrderStatementWriteOffCode(HttpServletRequest request, @PathVariable @ApiParam(value = "工单ID", required = true) Long workId) throws SMSException {
        AccounLoginInfo loginInfo = TokenUtil.getAccountLoginInfo(request);
        conWorkOrderService.getStatementWriteOffCode(loginInfo, workId);
        return Result.success("发送结单核销码成功");
    }

    @ApiOperation("工单超时提醒")
    @PostMapping("/workTimeoutRemind")
    public Result workTimeoutRemind(HttpServletRequest request, @RequestBody @Valid WorkTimeoutRemindVo workTimeoutRemindVo) throws ZbException {
        AccounLoginInfo loginInfo = TokenUtil.getAccountLoginInfo(request);
        return Result.success("工单超时提醒发送成功").data(PageUtil.row(conWorkOrderService.workTimeoutRemind(loginInfo, workTimeoutRemindVo)));
    }

    @ApiOperation("获取工单最新进展")
    @GetMapping("/getOrderLastLog/{workId}")
    public Result getOrderLastLog(@PathVariable @ApiParam(value = "工单ID") Long workId) {
        return Result.success("获取最新进展").data(PageUtil.row(workLogService.getOrderLastLogByWorkId(workId)));
    }

    @ApiOperation("更改结算价")
    @PostMapping("/updateSettlementPrice")
    public Result updateSettlementPrice(HttpServletRequest request, @RequestBody @Valid WorkSettlementPriceVo workSettlementPriceVo) {
        AccounLoginInfo loginInfo = TokenUtil.getAccountLoginInfo(request);
        conWorkOrderService.updateSettlementPrice(loginInfo, workSettlementPriceVo);
        return Result.success("更新结算价成功");
    }

    @ApiOperation("根据工单ID获取结单字段")
    @GetMapping("/getOrderSettlementField/{workId}")
    public Result getOrderSettlementField(@PathVariable @ApiParam(value = "工单ID", required = true) Long workId) {
        return Result.success("获取结单字段成功").data(PageUtil.rows(conWorkOrderService.getOrderSettlementField(workId)));
    }

    @ApiOperation("导出工单明细")
    @GetMapping("/exportWorkOrderDetail/{workId}")
    public Result exportWorkOrderDetail(@PathVariable @ApiParam(value = "工单ID", required = true) Long workId) {
        return Result.success("导出工单明细成功").data(PageUtil.rows(conWorkOrderService.getWorkOrderDetailsPrinted(workId)));
    }

    @ApiOperation("工单再次上门")
    @PostMapping("/workAgain")
    public Result workAgain(@RequestBody ZjWorkOrder zjWorkOrder) {
        conWorkOrderService.workAgain(zjWorkOrder);
        return Result.success("工单再次上门");
    }

    @ApiOperation("提交服务商签单图")
    @PostMapping("/signImage")
    public Result signImage(@RequestBody JSONObject jsonObject) {
        // 从jsonObject中获取urls JSONArray
        JSONArray jsonArray = jsonObject.getJSONArray("urls");

        // 获取id
        Long id = jsonObject.getLong("id");
        List<String> urlsList = jsonArray.toJavaList(String.class);
        // 将List<String>转换为用逗号分隔的字符串
        String urlsStr = String.join(",", urlsList);

        ZjWorkOrder zjWorkOrder = new ZjWorkOrder();
        zjWorkOrder.setId(id);
        zjWorkOrder.setSignImage(urlsStr);
        conWorkOrderService.signImage(zjWorkOrder);
        return Result.success("提交服务商签单图");
    }
    @ApiOperation("客服核实派单时间")
    @PostMapping("/workOrder/verifyVisitTime")
    public Result verifyVisitTime(HttpServletRequest request, @RequestBody @Valid OrderVerifyVisitTimeVo verifyVisitTimeVo) {
        AccounLoginInfo loginInfo = TokenUtil.getAccountLoginInfo(request);
        conWorkOrderService.saveVerifiedVisitTime(loginInfo, verifyVisitTimeVo);
        return Result.success();
    }







}
